文章目录

端与 H5 Bridge 交互学习笔记

适合目标:6 小时内快速建立 Hybrid 开发与 JSBridge 交互体系,覆盖 H5 与 Native 双向通信原理、iOS / Android 实现方式、协议设计、安全问题、常见业务场景与高频面试题。
学习重点:H5 怎么调端、端怎么调 H5、Bridge 协议怎么设计、异步回调怎么处理、安全风险怎么规避。
学习原则:先理解“为什么需要 Bridge”,再记通信方式;先掌握双向通信主链路,再记平台细节;先会讲原理,再会写封装。


目录

  1. 学习总览
  2. Hybrid 与 Bridge 到底在解决什么
  3. Bridge 核心通信模型
  4. H5 调 Native
  5. Native 调 H5
  6. JSBridge 协议设计与封装
  7. iOS / Android 实现思路
  8. 常见业务场景与实战链路
  9. 安全、稳定性与调试排查
  10. 高频面试题
  11. 更好记的学习方法
  12. 6 小时学习节奏建议
  13. 一页速记总结
  14. 背诵口诀

1. 学习总览

1.1 什么是端与 H5 Bridge 交互

这里说的“端”,通常指:

  1. iOS App
  2. Android App

这里说的 H5,通常指:

  1. WebView 里的网页
  2. Hybrid 应用中的前端页面

Bridge 可以理解成:

让 H5 和 Native 互相发消息的一座桥。

1.2 为什么需要 Bridge

单纯的 H5 页面能力有限,很多原生能力它拿不到,比如:

  1. 相机
  2. 相册
  3. 定位
  4. 支付
  5. 登录态
  6. App 页面跳转
  7. 系统分享

而 Native 也常常需要控制 H5,比如:

  1. 把登录信息同步给 H5
  2. 通知 H5 刷新数据
  3. 主动触发 H5 某个方法
  4. 把原生结果回传给页面

所以 Bridge 的本质就是:

解决 WebView 中 H5 和原生之间的双向通信问题。

1.3 学习这部分要抓哪条主线

你可以把这块知识压成两句话:

  1. H5 调端:H5 把消息发给 Native,Native 执行能力后再把结果回回来
  2. 端调 H5:Native 主动执行 H5 的某个 JS 方法

只要把这两条主线弄清楚,后面很多细节都容易挂上去。

1.4 核心记忆主线

把 Bridge 记成一句话:

H5 不直接拥有原生能力,Bridge 负责把“消息”变成“原生动作”。

再压缩成四个词:

发消息、执行、回调、同步


2. Hybrid 与 Bridge 到底在解决什么

2.1 什么是 Hybrid 开发

Hybrid 开发可以简单理解成:

页面用 Web 技术写,容器和系统能力由 App 提供。

典型结构:

  1. App 里嵌一个 WebView
  2. WebView 加载 H5 页面
  3. 页面显示 UI
  4. 原生提供设备能力和容器能力

2.2 为什么企业里经常用 H5 + App 组合

原因很现实:

  1. H5 更新快,不用频繁发版
  2. 一套页面能跨平台复用
  3. 活动页、营销页、配置页很适合 H5
  4. 复杂设备能力和性能敏感部分仍交给 Native

2.3 纯 H5 和 Hybrid 的核心区别

维度 纯浏览器 H5 App 内 H5
运行环境 浏览器 WebView
系统能力 受浏览器限制 可通过 Bridge 间接使用原生能力
登录态 浏览器 Cookie / Token 可能需要和 App 登录体系打通
页面控制 浏览器行为 可被 Native 容器控制

2.4 Bridge 到底在架构里处于什么位置

Bridge 不是业务本身,它更像一个中间层:

H5 业务代码 -> JSBridge -> Native Bridge 层 -> 原生业务模块

也就是说:

  1. H5 不应该直接理解原生实现细节
  2. Native 也不该直接暴露过多底层接口给 H5
  3. Bridge 层负责把双方解耦

2.5 面试里怎么概括 Bridge

标准答法可以这样说:

JSBridge 是 Hybrid 架构中用于连接 WebView 内 H5 页面和 Native 容器的通信层,它负责把 H5 的调用请求转发给原生模块执行,并把执行结果或状态再回传给 H5,从而实现双向通信。


3. Bridge 核心通信模型

3.1 先记住最重要的一张脑图

Bridge 通信最核心的链路可以记成:

H5 发请求 -> Native 接收 -> Native 执行 -> Native 回传 -> H5 更新页面

如果是反向:

Native 发指令 -> H5 接收 -> 执行页面逻辑 -> 返回结果

3.2 双向通信的两个方向

方向 1:H5 调 Native

场景:

  1. 打开相机
  2. 获取用户信息
  3. 调起支付
  4. 关闭当前页面

方向 2:Native 调 H5

场景:

  1. 告诉 H5 登录成功
  2. 把定位结果回传给 H5
  3. 通知 H5 刷新
  4. 让 H5 执行某个 JS 方法

3.3 一次完整调用通常有哪些字段

不管你用什么实现方式,消息结构最好统一。

一个典型请求消息可以这样设计:

{
  "module": "device",
  "method": "getLocation",
  "params": {
    "timeout": 3000
  },
  "callbackId": "cb_1001"
}

返回消息可以这样设计:

{
  "callbackId": "cb_1001",
  "code": 0,
  "message": "success",
  "data": {
    "lat": 39.9,
    "lng": 116.3
  }
}

3.4 为什么 callbackId 很重要

因为很多 Bridge 调用是异步的,比如:

  1. 选图
  2. 定位
  3. 支付
  4. 登录

这时 H5 发请求后,不会立刻拿到结果。

所以必须用 callbackId 把:

  1. 这次请求
  2. 未来返回的结果

对应起来。

3.5 最常见的 Bridge 协议字段

字段 作用
module 模块名,如 deviceusershare
method 调用的方法名
params 调用参数
callbackId 用于异步回调匹配
code 状态码
message 状态描述
data 返回数据

3.6 一句话压缩通信模型

Bridge 本质上是基于消息协议的双向调用。


4. H5 调 Native

这一部分是最核心、最常考的内容。你要牢牢记住一句话:H5 调端,本质上是 H5 想办法把“调用消息”送到 Native。

4.1 H5 调端有哪些常见方式

历史和现代方案可以分成几类:

  1. URL Scheme 拦截
  2. iframe 触发 Scheme
  3. prompt / alert 拦截
  4. 注入对象方式
  5. postMessage 方式

4.2 URL Scheme 方案是什么

H5 通过构造一个特殊 URL:

myapp://bridge?data=...

然后让 WebView 去加载它。

Native 拦截这个请求后:

  1. 识别这是 Bridge 消息
  2. 解析参数
  3. 执行对应原生逻辑

4.3 为什么早期常用 iframe + scheme

因为早期某些环境里,H5 很难直接和 Native 通信,所以会借助一个隐藏 iframe

const iframe = document.createElement("iframe");
iframe.style.display = "none";
iframe.src = "myapp://bridge?data=...";
document.body.appendChild(iframe);
document.body.removeChild(iframe);

这个动作的本质是:

借助一次 URL 加载行为,把消息送给 Native。

4.4 URL Scheme 方案的优缺点

优点

  1. 思路简单
  2. 兼容一些旧环境
  3. 适合早期 Hybrid 方案

缺点

  1. 传参能力有限
  2. 编码麻烦
  3. 容易受 URL 长度限制影响
  4. 回调处理不够优雅
  5. 调试体验一般

4.5 注入对象方式是什么

这是更现代也更常见的方式。

Native 在 WebView 里注入一个 JS 可访问对象,例如:

window.NativeBridge.postMessage(...)

然后 H5 直接调用这个对象的方法,把消息交给 Native。

4.6 H5 侧调用示例

function callNative(module, method, params = {}) {
  const callbackId = `cb_${Date.now()}_${Math.random()}`;

  const message = {
    module,
    method,
    params,
    callbackId,
  };

  window.NativeBridge.postMessage(JSON.stringify(message));
}

4.7 为什么注入对象方式更好理解

因为它更像普通函数调用:

  1. H5 直接调一个 JS 可访问对象
  2. Native 接收到消息
  3. Native 再回调 H5

相比 Scheme,更像“真实接口调用”。

4.8 H5 调端时最常见的场景

  1. getUserInfo
  2. getToken
  3. openCamera
  4. chooseImage
  5. share
  6. pay
  7. closePage
  8. openPage
  9. getLocation
  10. copyText

4.9 为什么 H5 调端一般要封装 Promise

因为很多调用是异步的,如果不用 Promise,调用会很难看:

  1. 回调层级多
  2. 代码不统一
  3. 不好处理超时和错误

Promise 封装后,调用体验会更好。

示例:

const callbackMap = new Map();

function callNative(module, method, params = {}) {
  return new Promise((resolve, reject) => {
    const callbackId = `cb_${Date.now()}_${Math.random()}`;

    callbackMap.set(callbackId, { resolve, reject });

    const message = {
      module,
      method,
      params,
      callbackId,
    };

    window.NativeBridge.postMessage(JSON.stringify(message));

    setTimeout(() => {
      if (callbackMap.has(callbackId)) {
        callbackMap.delete(callbackId);
        reject(new Error("bridge timeout"));
      }
    }, 5000);
  });
}

4.10 H5 收原生回调怎么做

通常 Native 会主动执行 H5 某个全局方法,比如:

window.__bridgeCallback = function (response) {
  const { callbackId, code, data, message } =
    typeof response === "string" ? JSON.parse(response) : response;

  const task = callbackMap.get(callbackId);
  if (!task) return;

  callbackMap.delete(callbackId);

  if (code === 0) {
    task.resolve(data);
  } else {
    task.reject(new Error(message || "bridge error"));
  }
};

4.11 H5 调 Native 一句话压缩

H5 调端就是把调用消息交给 Native,再通过 callbackId 把异步结果接回来。


5. Native 调 H5

很多人只记得 H5 调端,容易忽略反向通信。但面试里非常爱问:端怎么主动通知 H5?

5.1 Native 调 H5 本质是什么

本质上就是:

Native 主动执行 WebView 里的某段 JavaScript。

例如执行:

window.onLoginSuccess({...})

5.2 Android 常见方式

Android 常见做法是:

webView.evaluateJavascript("window.onLoginSuccess(" + json + ")", null);

老一点也可能看到:

webView.loadUrl("javascript:window.onLoginSuccess(" + json + ")");

通常更推荐 evaluateJavascript,因为:

  1. 更现代
  2. 性能更好
  3. 可直接拿返回值

5.3 iOS 常见方式

iOS 常见做法是:

webView.evaluateJavaScript("window.onLoginSuccess(\(json))", completionHandler: nil)

5.4 为什么端调 H5 也最好走统一协议

因为 Native 调 H5 不能每个业务都随意拼 JS 字符串,否则会出现:

  1. 方法名不统一
  2. 参数结构混乱
  3. 调试困难
  4. 安全风险高

更好的做法是:

window.__receiveFromNative({
  event: "loginSuccess",
  data: {...}
});

5.5 一个统一接收入口示例

window.__receiveFromNative = function (message) {
  const payload =
    typeof message === "string" ? JSON.parse(message) : message;

  const { event, data } = payload;

  switch (event) {
    case "loginSuccess":
      handleLoginSuccess(data);
      break;
    case "locationUpdate":
      handleLocationUpdate(data);
      break;
    default:
      console.warn("unknown native event:", event);
  }
};

5.6 Native 调 H5 常见业务

  1. 登录成功通知
  2. 支付结果通知
  3. 分享回调通知
  4. App 前后台状态通知
  5. 定位变化通知
  6. 页面 resume / pause 通知

5.7 端调 H5 一句话压缩

端调 H5 本质是执行页面里的 JS 方法,最好统一走事件分发入口。


6. JSBridge 协议设计与封装

真正能体现你工程能力的,不是“知道有 Bridge”,而是“知道怎么把它设计得可维护”。

6.1 为什么要有统一协议

如果没有统一协议,Bridge 很容易变成这样:

  1. 每个业务自己拼参数
  2. 方法名风格不一致
  3. 返回结构五花八门
  4. 错误处理不统一
  5. 很难做版本演进

所以实际项目里,一定要设计协议层。

6.2 推荐的协议结构

请求:

{
  "version": "1.0.0",
  "module": "user",
  "method": "getProfile",
  "params": {},
  "callbackId": "cb_1"
}

响应:

{
  "version": "1.0.0",
  "callbackId": "cb_1",
  "code": 0,
  "message": "success",
  "data": {
    "name": "Tom"
  }
}

6.3 为什么要加 version

因为 Bridge 也是一套接口协议。

随着 App 和 H5 版本演进,协议可能变化。

version 后:

  1. 方便兼容旧版本
  2. 方便灰度升级
  3. 方便排查线上问题

6.4 为什么 module + method 比一个大方法更好

因为它更清晰:

  1. module 表示能力域
  2. method 表示具体动作

例如:

  • user.getToken
  • device.getLocation
  • app.closePage

这样比只传一个字符串更容易维护。

6.5 为什么要封装成 SDK

前端不应该每次都自己拼协议。

更好的做法是提供:

bridge.getToken()
bridge.openCamera()
bridge.closePage()

而不是业务代码里到处写:

callNative("device", "openCamera", {...})

6.6 一层好的 H5 SDK 应该做什么

  1. 环境检测
  2. 参数校验
  3. Promise 封装
  4. 超时处理
  5. 回调清理
  6. 错误兜底
  7. 版本兼容

6.7 环境检测为什么重要

因为你的 H5 不一定总在 App 内运行,也可能:

  1. 在浏览器中打开
  2. 在测试容器中打开
  3. 在某个平台 App 中打开

所以要先判断:

  1. 当前是否在 App 内
  2. 当前是 Android 还是 iOS
  3. 当前 Bridge 是否已注入完成

6.8 Bridge Ready 为什么重要

Bridge 对象可能不是页面一加载就立刻可用。

所以很多项目会有一个:

bridge ready

机制,表示:

Native 注入完成,现在 H5 可以安全调用。

6.9 常见封装示例

const bridge = {
  getToken() {
    return callNative("user", "getToken");
  },
  openCamera(options) {
    return callNative("device", "openCamera", options);
  },
  closePage() {
    return callNative("app", "closePage");
  },
};

6.10 错误码体系最好统一

例如:

code 含义
0 成功
1001 参数错误
1002 Bridge 未就绪
1003 Native 不支持该方法
1004 用户取消
1005 超时

6.11 为什么要支持回调和事件两种模式

因为并不是所有消息都是“请求 -> 响应”。

有些是主动通知:

  1. 登录状态变化
  2. 网络状态变化
  3. 页面可见性变化

这类更适合事件机制,而不是 Promise 回调。

6.12 一句话压缩协议设计

Bridge 要像一套小型 RPC 协议来设计,而不是临时拼几个字符串。


7. iOS / Android 实现思路

这里你不一定要记住全部平台 API 细节,但一定要知道各平台的实现方向。

7.1 Android 常见实现思路

Android 里常见几种方式:

  1. addJavascriptInterface
  2. URL 拦截
  3. evaluateJavascript

H5 -> Android

常见方式:

webView.addJavascriptInterface(new NativeBridgeHandler(), "NativeBridge");

然后 H5 可调用:

window.NativeBridge.postMessage(...)

Android -> H5

常见方式:

webView.evaluateJavascript("window.__receiveFromNative(" + json + ")", null);

7.2 Android 的安全注意点

addJavascriptInterface 是高频考点。

要记住:

  1. 早期 Android 版本有安全风险
  2. 暴露给 JS 的接口不能过宽
  3. 不要把敏感能力全部无条件开放
  4. 只开放经过白名单设计的接口

7.3 iOS 常见实现思路

iOS 现代 WebView 通常使用 WKWebView

H5 -> iOS

可以通过:

window.webkit.messageHandlers.NativeBridge.postMessage(...)

原生侧通过 WKScriptMessageHandler 接收。

iOS -> H5

通过:

webView.evaluateJavaScript("window.__receiveFromNative(\(json))")

7.4 iOS 常见要记的点

  1. 常用 WKWebView
  2. JS 发消息给 Native 走 messageHandlers
  3. Native 调 H5 通常走 evaluateJavaScript

7.5 iOS 和 Android 共同点

共同点永远是:

  1. H5 发消息
  2. Native 接收并执行
  3. Native 再主动调用 JS 回传结果

7.6 iOS 和 Android 区别怎么记

你不用死背所有 API,只记这一层:

方向 Android iOS
H5 -> Native addJavascriptInterface / 拦截方案 WKScriptMessageHandler
Native -> H5 evaluateJavascript evaluateJavaScript

7.7 一个跨平台思维方式

前端最好不要在业务层写:

if (isAndroid) ...
if (isIOS) ...

更好的方式是:

  1. 平台差异收敛到 Bridge SDK 层
  2. 业务层只面向统一 API

这才是更工程化的设计。

7.8 一句话压缩平台实现

平台细节可以不同,但对前端暴露的 Bridge 能力应该统一。


8. 常见业务场景与实战链路

8.1 获取登录信息

常见流程:

  1. H5 调 user.getToken
  2. Native 从本地登录态里取 token
  3. 回传给 H5
  4. H5 用这个 token 请求后端接口

8.2 打开相机 / 相册

常见流程:

  1. H5 调 device.openCamera
  2. Native 申请权限
  3. 打开相机
  4. 拍照完成后返回图片地址或文件信息
  5. H5 更新页面

8.3 支付

常见流程:

  1. H5 调 payment.pay
  2. Native 拉起支付 SDK
  3. 支付结束
  4. Native 将支付结果回传 H5
  5. H5 根据结果显示成功或失败

8.4 分享

常见流程:

  1. H5 组织分享标题、描述、链接、图片
  2. share.open
  3. Native 调起系统分享面板或 App 分享面板
  4. 结果回传 H5

8.5 页面跳转

常见有两种:

  1. H5 内部路由跳转
  2. H5 请求 Native 打开新原生页

例如:

bridge.openPage({
  url: "/native/user/profile",
  params: { userId: 1001 },
});

8.6 关闭页面

这是高频场景,很多 App 内 H5 都要支持:

bridge.closePage();

8.7 拉取设备信息

例如:

  1. 系统版本
  2. 设备型号
  3. App 版本
  4. 网络状态

这类场景常用于:

  1. 页面适配
  2. 问题排查
  3. 功能开关判断

8.8 登录态同步为什么常考

因为它涉及:

  1. App 登录系统
  2. H5 接口鉴权
  3. 页面刷新时机
  4. 多页面状态同步

如果你能把这类场景讲清楚,面试官会觉得你不是只懂概念。

8.9 事件型通知场景

例如:

  1. App 从后台切回前台
  2. 定位变化
  3. 登录状态变更
  4. 网络状态变化

这类更适合:

Native -> H5 事件通知

8.10 一句话压缩业务场景

凡是 H5 缺能力时就需要调端,凡是 Native 需要通知页面时就需要反向调用。


9. 安全、稳定性与调试排查

这部分特别重要。面试里如果你能主动谈安全和稳定性,回答会立刻显得更成熟。

9.1 Bridge 的安全风险有哪些

常见风险:

  1. 任意 H5 页面都能调用敏感原生能力
  2. 暴露的原生接口过多
  3. 参数没校验,可能造成逻辑滥用
  4. 直接拼接 JS 字符串,存在注入风险
  5. Android 注入接口过宽导致安全问题

9.2 最基本的安全策略

  1. 域名白名单
  2. 能力白名单
  3. 参数校验
  4. 敏感操作二次确认
  5. 不暴露通用执行任意命令的接口
  6. 对返回数据做最小化设计

9.3 为什么不能给 H5 一个“万能调用接口”

例如这种设计就很危险:

bridge.exec("任意原生方法名", 任意参数)

问题在于:

  1. 权限边界不清晰
  2. 很难控制安全范围
  3. 很难审计

更好的方式是:

只开放明确、白名单化、文档化的接口

9.4 稳定性问题有哪些

  1. Bridge 还没 ready 就调用
  2. 页面销毁后回调还回来
  3. 多次回调同一个 callbackId
  4. 回调没清理导致内存泄漏
  5. App 版本过低不支持某方法
  6. H5 不在 App 内运行

9.5 为什么要处理页面销毁

例如 H5 调了相机:

  1. 用户中途返回
  2. 页面已销毁
  3. 原生结果才回来

如果这时还强行回调页面,就会出问题。

所以要注意:

  1. 页面卸载时清理 callbackMap
  2. Native 回调前检查页面是否仍有效

9.6 超时机制为什么重要

Bridge 不是 HTTP 接口,不代表它不会超时。

像:

  1. 用户不授权定位
  2. 用户不完成支付
  3. 相机权限卡住

都可能让调用长期悬空。

所以要有:

  1. 超时兜底
  2. 用户取消态
  3. 错误码返回

9.7 调试时先看哪几层

遇到 Bridge 问题时,建议按这条链排查:

  1. H5 是否真的发了消息
  2. 消息格式是否正确
  3. Native 是否拦截或接收到
  4. Native 是否执行成功
  5. Native 是否正确回调 H5
  6. H5 是否正确解析回调

9.8 常见排查案例

案例 1:H5 调端没反应

优先检查:

  1. Bridge 是否 ready
  2. 是否在 App 环境中
  3. 接口名是否写错
  4. Native 是否已实现该接口

案例 2:回调拿不到

优先检查:

  1. callbackId 是否传了
  2. 回调函数是否被覆盖
  3. Native 是否真的回调
  4. 页面是否提前销毁

案例 3:某些手机可以,某些不行

优先检查:

  1. App 版本差异
  2. Android / iOS 实现差异
  3. WebView 版本差异
  4. 权限差异

9.9 日志为什么很重要

建议 Bridge 层至少打这些日志:

  1. 请求时间
  2. 模块和方法名
  3. 参数摘要
  4. 回调结果
  5. 错误码
  6. 耗时

9.10 一句话压缩安全与稳定性

Bridge 问题通常不是“能不能调”,而是“是否可控、可回溯、可兼容、可收敛”。


10. 高频面试题

10.1 什么是 JSBridge

可以答:

JSBridge 是 Hybrid 架构中连接 H5 和 Native 的通信桥梁,H5 可以通过它调用原生能力,Native 也可以通过它通知或控制 H5 页面。

10.2 为什么 H5 需要 Bridge

可以答:

因为 WebView 内的 H5 无法直接访问所有原生能力,比如相机、定位、支付、登录态等,所以需要 Bridge 作为中间层转发调用。

10.3 H5 调 Native 的本质是什么

可以答:

本质上是 H5 把一条调用消息传给 Native,Native 解析并执行后,再通过回调把结果返回给 H5。

10.4 Native 调 H5 的本质是什么

可以答:

本质上是 Native 主动执行 WebView 中的 JavaScript 方法。

10.5 常见的 Bridge 实现方式有哪些

可以答:

  1. URL Scheme 拦截
  2. iframe + scheme
  3. prompt / alert 拦截
  4. 注入对象方式
  5. postMessage 方案

10.6 URL Scheme 和注入对象方式的区别是什么

可以答:

URL Scheme 更偏早期方案,本质是借助 URL 加载让 Native 拦截消息;注入对象方式更现代,调用更像普通 JS 接口,传参和封装体验通常更好。

10.7 为什么需要 callbackId

可以答:

因为很多 Bridge 调用是异步的,需要用 callbackId 把发起请求和未来回来的结果对应起来。

10.8 为什么要封装 Promise

可以答:

因为 Bridge 调用大量是异步行为,用 Promise 可以统一调用形式,方便处理超时、错误和业务串联。

10.9 Bridge 有哪些安全风险

可以答:

主要风险包括暴露敏感能力过多、任意页面可调用、参数未校验、直接执行拼接 JS 带来的注入风险,以及 Android 注入接口过宽等问题。

10.10 如何设计一个好的 Bridge 协议

可以答:

  1. 统一 modulemethodparamscallbackId
  2. 返回统一 codemessagedata
  3. 支持版本号
  4. 有错误码体系
  5. 有超时和回调清理机制

10.11 为什么要做环境检测

可以答:

因为同一套 H5 不一定总运行在 App 内,也可能运行在普通浏览器或不同平台容器里,所以调用前必须识别当前环境和 Bridge 是否可用。

10.12 如果 Bridge 调用失败,你会怎么排查

推荐答法:

  1. 看 H5 是否发起调用
  2. 看消息格式是否正确
  3. 看 Native 是否收到
  4. 看 Native 是否执行成功
  5. 看回调是否正确触发
  6. 看页面是否正确接收和解析

10.13 为什么业务层不应该直接写平台分支

可以答:

因为平台差异应该收敛在 Bridge SDK 层,业务层只关心统一能力接口,这样才能减少耦合并提升维护性。

10.14 实战里最常见的 Bridge 场景有哪些

可以答:

登录态同步、支付、分享、打开相机、相册选择、定位、页面关闭和原生页面跳转,是最常见的几类场景。


11. 更好记的学习方法

11.1 用一句话记住 Bridge

H5 调不到原生能力,所以要通过一座桥把消息交给 Native。

11.2 用“双向”来记

你只要记住两个方向:

  1. H5 -> Native
  2. Native -> H5

其余知识基本都是这两个方向的细化。

11.3 用“谁主动”来记

  • H5 主动:请求能力
  • Native 主动:通知页面

11.4 用对比法记

对比 1:H5 调端 vs 端调 H5

  • H5 调端:发消息给 Native
  • 端调 H5:执行 JS 方法

对比 2:Scheme vs 注入对象

  • Scheme:借 URL 加载传消息
  • 注入对象:像调 JS 接口

对比 3:回调 vs 事件

  • 回调:一问一答型
  • 事件:主动通知型

11.5 用口诀记

  1. H5 调端靠发消息,端调 H5 靠执行 JS
  2. 请求要带 callbackId,返回要有 code 和 data
  3. 业务层别碰平台差异,统一收敛到 SDK
  4. 能力要白名单,调用要可追踪

11.6 最有效的记忆方式

你最好能做到这四件事:

  1. 画出 Bridge 双向通信图
  2. 手写一个 Promise 封装
  3. 讲清一个登录态同步场景
  4. 回答 10 个面试题

如果这四件事都能完成,你就不只是“看过”,而是真的掌握了。


12. 6 小时学习节奏建议

第 1 小时:建立总框架

目标:

  1. 理解 Hybrid 是什么
  2. 理解为什么需要 Bridge
  3. 记住双向通信两条主线

输出目标:

能用自己的话解释什么是 JSBridge

第 2-3 小时:集中突破通信原理

重点:

  1. H5 调 Native
  2. Native 调 H5
  3. callbackId
  4. Promise 封装
  5. 协议字段

输出目标:

能把一次完整 Bridge 调用链路讲清楚

第 4 小时:平台实现与协议设计

重点:

  1. Android 思路
  2. iOS 思路
  3. Bridge SDK 设计
  4. 事件机制
  5. 版本兼容

输出目标:

能说明为什么业务层应该面向统一 Bridge SDK

第 5 小时:常见业务场景

重点:

  1. 登录态同步
  2. 支付
  3. 分享
  4. 相机和相册
  5. 页面跳转和关闭

输出目标:

能讲 2-3 个真实业务链路

第 6 小时:安全、排查、面试冲刺

重点:

  1. 白名单和权限边界
  2. 注入风险
  3. 超时和页面销毁
  4. 调试排查路径
  5. 高频面试题

输出目标:

能按“原理 -> 实现 -> 风险 -> 排查”顺序完整回答问题


13. 一页速记总结

13.1 Bridge 核心定义

JSBridge 是 H5 与 Native 之间的双向通信层。

13.2 两条主线

  • H5 -> Native:H5 发消息给原生
  • Native -> H5:原生执行 JS 方法

13.3 一次标准调用

请求:

  • module
  • method
  • params
  • callbackId

响应:

  • callbackId
  • code
  • message
  • data

13.4 常见实现方式

  • Scheme 拦截
  • 注入对象
  • messageHandlers
  • evaluateJavascript / evaluateJavaScript

13.5 工程化重点

  • Promise 封装
  • 统一协议
  • 统一 SDK
  • 事件机制
  • 版本兼容

13.6 安全重点

  • 域名白名单
  • 能力白名单
  • 参数校验
  • 不暴露敏感万能接口

13.7 最重要的一句话

Bridge 不是随便传消息,而是一个需要协议化、白名单化、可回溯的通信层。


14. 背诵口诀

14.1 总口诀

H5 要能力,先过桥;端要通知,调 JS。

14.2 通信口诀

H5 发消息,Native 去执行;执行完结果,再按回调回。

14.3 协议口诀

请求四件套:模块、方法、参数、回调;返回四件套:回调、状态、信息、数据。

14.4 工程化口诀

业务不碰平台差异,统一收口 Bridge SDK。

14.5 安全口诀

接口要白名单,参数要校验,敏感能力要收紧。

14.6 面试口诀

回答 Bridge 题时,尽量按这个顺序说:

  1. 它解决什么问题
  2. 双向通信怎么做
  3. 协议怎么设计
  4. 有哪些安全风险
  5. 实战里怎么排查

只要你按这个顺序说,答案通常就比较完整。


附:你可以怎么用这份笔记

第一次学习

重点看:

  1. 学习总览
  2. Bridge 核心通信模型
  3. H5 调 Native
  4. Native 调 H5

第二次复习

重点看:

  1. 协议设计与封装
  2. iOS / Android 实现思路
  3. 常见业务场景

第三次冲刺

只看:

  1. 一页速记总结
  2. 背诵口诀
  3. 高频面试题

如果你能把这三部分不看笔记讲出来,说明你已经真正掌握了 Bridge 交互这块内容。